/* 参考InsertAsmSrc.h格式对2019年新增的代码做一些注释。因为不是专业人士，所以部分内容和格式可能有误。

////////////////////////////////////////////////////////////////////////////////////////////////
//captive money2
		__asm{;俘虏【回复交还】界面选择【资金】默认输入系统判定的当前俘虏价值资金数
			;输入：ecx=任务指针，[esp+28h]=最小值=1，[esp+30h]=默认值=1
			;输出：[esp+30h]=系统判断值
			;空闲寄存器：eax,edx
			{;patch:
			push    dword ptr [ecx+11B8h];当前俘虏
			push    dword ptr [ecx+11B4h];俘虏所在势力
			push    dword ptr [ecx+11B0h];交还武将
			mov     eax, 0048F570h;系统俘虏价值函数，函数执行时会保存和恢复ecx  
			call    eax
			add     esp, 0Ch;恢复堆栈
			mov     dword ptr [esp+30h], eax;修改默认值  
			push    004CB790h;跳转到原函数 
			retn},
			{;thunk: Addr = 0x4F9DDF
			}	
		}
////////////////////////////////////////////////////////////////////////////////////////////////		
//sort exchange captive
		__asm{;排序电脑交还俘虏时，考虑俘虏的忠诚度
			;俘虏武将四维最高值*460 + 武将四维和
			;=>(俘虏武将四维最高值 + (85<武将的自忠诚度<135 ? 25 : 0))*460 + 武将四维和
			;输入：eax=esi=俘虏武将指针
			;输出：eax=修正的排序指标
			;空闲寄存器：ecx,edx,edi
			{;patch:
			},
			{;thunk: Addr = 0x4AFC59
			jmp		normal
			xor		eax,eax;原代码武将指针无效，排序指标=0	
			jmp		end
		normal:
			push	eax;俘虏武将指针
			call	004AFBC0h;获得武将四维最高值
			mov		edi,eax
			pop		ecx;从堆栈恢复ecx
			call	0044DE00h;获得武将自忠诚度
			cmp		eax,87h;>135?
			jg		ignore_loyalty
			cmp		eax,55h;<85?
			jl		ignore_loyalty
			add		edi,19h;四维最高值 += 25
		ignore_loyalty:
			imul	edi, edi, 1CCh;四维最高值*460
			mov		ecx,esi
			call	0044D3A0h;获得武将四维和
			add		eax,edi
		end:
			pop		edi
			}
			;ps:本代码尚未加入优化，因为修正排序指标后，对于部分武将电脑赎回概率好像下降了，有待进一步分析
		}
/////////////////////////////////////////////////////////////////////////////////////////
//add water killer
		__asm{;艨艟增加兵法“箭雨”
			;输入：
			;输出：
			;空闲寄存器：
			{;patch:
			mov     ecx, dword ptr [esi+84h];目标部队?
			mov     eax, dword ptr [ecx]
			call    dword ptr [eax+0B4h];部队所在地图块在水上? 
			test    eax, eax
			je      end
			mov     ecx, dword ptr [edi];edi=源部队?
			mov     eax, dword ptr [esi+84h]
			mov     edx, dword ptr [ecx]
			push    1
			push    eax
			call    dword ptr [edx+0A8h];源部队与目标部队接触??
			test    eax, eax
			je      end
			push    502075;jmp强袭代码
			retn
	    end:  
			push    50203D;jmp箭雨代码
			retn
			},
			{;thunk: Addr = 0x50217C
			dd patchAddr
			}
			;ps:这段代码是仿照00501FE0h()代码段鬥舰的兵法代码写的，没什么差错，也就没动态跟踪仔细研究，注释比较模糊
		}
//enable water killer
		__asm{;允许/不能发动“箭雨”，“箭岚”
			;输入：eax=兵法序号，不能发动的返回地址
			;输出：修正的返回地址
			;空闲寄存器：eax,ecx,edx
			{;patch:
			cmp     eax, 17h;兵法序号=箭岚?
			je      enable
			cmp     eax, 15h;兵法序号=箭雨?
			je      enable
			retn
		enable:
			add     byte ptr [esp], 4;可以发动的返回地址
			retn
			},
			{;thunk: Addr = 0x5038A7
			}
		}
///////////////////////////////////////////////////////////////////////
//auto adjust killer
		__asm{;出征界面点【阵型】选中部分阵型时自动变更武将兵法（包括势力兵法和宝物附加兵法）
			;输入：ebp=任务指针，esi=武将
			;输出：选择兵法指针=>武将(8)
			;空闲寄存器：eax,ecx,edx
			{;patch:
			mov     eax, dword ptr [ebp+74Ch];选中阵型指针
			mov     al, byte ptr [eax+4];阵型序号
			xor     ecx, ecx;转换兵法类置零  
			cmp     al, 0;阵型=鱼鳞?
			jz      foot_killer
			cmp     al, 1;阵型=鹤翼?
			jz      foot_killer
			cmp     al, 3;阵型=锋矢?
			jz      horse_killer 
			cmp     al, 4;阵型=雁行?
			jz      bow_killer
			cmp     al, 6;阵型=长蛇?  
			jz      horse_bow_killer 
			cmp     al, 7;阵型=方圆?  
			jz      intelligence_killer
			cmp     al, 8;阵型=井阑? 
			jz      bow_killer
			jmp     end;其他阵型不做兵法转换 
		intelligence_killer: 
		;方圆=>智力类,ecx=4
			inc     ecx 
		bow_killer:
		;雁行/井阑=>弩兵类,ecx=3		
			inc     ecx
		horse_bow_killer:
		;长蛇=>弓骑类,ecx=2		
			inc     ecx
		horse_killer: 
		;锋矢=>骑兵类,ecx=1	
			inc     ecx
		foot_killer:
		;鱼鳞/鹤翼=>步兵类,ecx=0		
			cmp     ecx, 4;转换兵法类=智力类?
			jz      not_change_adjust_type
			mov     eax, dword ptr [esi+54];武将基本智力
			sub     eax, dword ptr [esi+4C];-基本武力
			cmp     eax, 0F;武将智力大于武力15以上?即部队军师?
			jle     not_change_adjust_type  
			mov     cl, 4;军师型武将,转换兵法类=>智力类
		not_change_adjust_type:
			push    ebx 
			push    ebp
			push    edi
			mov     ebx, 2;转换次数上限,武力类=2
			cmp     ecx, 4
			jnz     strength 
			mov     bl, 9;智力类=9
        strength: 	
			xor     ebp, ebp;转换次数置零
			lea     edi, dword ptr [ecx+ecx*2+killer_table_addr];各类型起始兵法序号地址
	    loop_check_killer:
			movzx   edx, byte ptr [edi+ebp];兵法号 
			mov     ecx, esi;武将
			push    edx
			mov     eax, 0044F770h;武将可使用push序号兵法(包括势力兵法和宝物附加兵法)?  
			call    eax
			test    eax, eax
			jnz     adjust_killer  
			inc     ebp;转换次数++
			cmp     ebp, ebx转换次数到达上限? 
			jle     loop_check_killer
			jmp     fail
	    adjust_killer:
			movzx   edx, byte ptr [edi+ebp];当前兵法序号   
			push    edx
			mov     eax, 00453720h;push兵法序号=>指针   
			call    eax
			add     esp, 4
			mov     dword ptr [esi+8], eax;兵法指针=>武将(8)
	    fail:
			pop     edi
			pop     ebp
			pop     ebx
	    end:
		;原代码
			add     ebx, 8 
			test    edi, edi
			retn
		killer_table:
			0x02, 0x01, 0x00,                            //foot_killer: 奋迅，奋斗，奋战；
			0x05, 0x04, 0x03,                            //horse_killer: 突击，突进，突破； 
			0x08, 0x07, 0x06,                            //horse_bow_killer: 飞射，奔射，骑射；
			0x0B, 0x0A, 0x09,                            //bow_killer: 连弩，连射，齐射；
			0x1A, 0x1E, 0x1D, 0x19, 0x16,                //intelligence_killer: 
			0x18, 0x17, 0x15, 0x1C, 0x1B                 //幻术，妖术，治疗，攻心，教谕；陷阱，混乱，破陷，鼓舞，辱骂。
			},
			{;thunk: Addr = 0x4E9207
			}
			;ps:第一段原创代码^_^,注释可能有点乱
		}
////////////////////////////////////////////////////////////////////////////////////////
//investment
		__asm{;玩家探索触发投资交易事件时，根据所属势力钱粮和分割点设定投资上限。
			;输入：ecx=军团资金，ebx=军团，esi=任务指针，
			;输出：ecx=修正的投资上限*5
			;空闲寄存器：eax,edx
			{;patch:
			push    edi   
			push    ecx
			mov     ecx, esi
			mov     eax, <San9PK.57fdd0h;交易·地点&类>
			call    eax
			xor     edi, edi;交易获得资源类型flag
			mov     edx, <San9PK.443010h;势力资金>
			cmp     eax, 5;交易获得资源=资金?
			jle     get_force_money/food
			inc     edi;交易获得资源=兵粮,flag=1
			mov     edx, <San9PK.443170h;势力兵粮>
	    	get_force_money/food:
			mov     ecx, dword ptr [ebx+0B8h];势力指针 
			call    edx 
			lea     ecx, dword ptr [edi+0Ch];钱/粮基本单位=2^(12/13)
			shr     eax, cl
			cmp     eax, 7Fh;钱/粮超出?
			jle     get_cut_point
			mov     al, 7Fh
	    	get_cut_point:
			xor     edx, edx;触发分割点数置零 
			lea     ecx, dword ptr [edi+edi*2+cut_point];&钱/粮最高分割点
	    	loop:
			cmp     al, byte ptr [ecx+edx];钱/粮小于当前分割点?
			jl      end_loop
			inc     edx;触发分割点数++  
			cmp     edx, 3;触发分割点数达到上限?
			jl      loop
		end_loop:
			sub     edx, 4
			neg     edx
			imul    edx, edx, 186A0h
			;修正数=(4-触发分割点数)*10W
			mov     ecx, edi
			shr     edx, cl
			;交易获得资源=兵粮，则修正数减半
			pop     ecx;恢复军团资金 
			cmp     edx, ecx;修正数>军团资金
			jge     end;不修正投资上限
			mov     ecx, edx;修正投资上限
        		end:	
			mov     eax, 66666667h;1/5魔数
			pop     edi
			retn
			},
			{;thunk: Addr = 0x580373
			}
		}
////////////////////////////////////////////////////////////////////////////////
//city population coef ;原//draft population
		__asm{;原优化兵役代码改为都市人口系数代码
			;输入：ecx=都市指针，edx=vptr
			;输出：eax=修正的都市民心=都市民心*都市人口系数参数/12
			;空闲寄存器：eax,ecx,edx
			{;patch:
			mov     eax, dword ptr [ecx+1C4h];原功能，获得都市民心
			movzx   edx, byte ptr [ecx+4];都市序号
			movzx   edx, byte ptr [edx+city_population_coef];根据都市序号获得都市人口系数参数
			imul    edx;民心*系数参数
			mov     ecx, 2AAAAAABh;1/6魔数
			imul    ecx
			sar     edx, 1
			mov     eax, edx
			shr     eax, 1F
			add     eax, edx;以上实现/12功能
			retn
		//city_population_coef:
			0x08, 0x08, 0x0C, 0x0E, 0x0C,              //襄平，北平，蓟，南皮，平原；
			0x12, 0x0C, 0x0C, 0x0E, 0x0E,              //邺，晋阳，上党，北海，濮阳；
			0x0E, 0x12, 0x0C, 0x0E, 0x0E,              //陈留，下邳，小沛，许昌，汝南；
			0x18, 0x18, 0x08, 0x08, 0x08,              //洛阳，长安，安定，天水，西平；
			0x08, 0x0E, 0x0C, 0x12, 0x0C,              //武威，寿春，庐江，建业，吴；
			0x08, 0x0E, 0x0E, 0x08, 0x12,              //会稽，柴桑，宛，新野，襄阳；
			0x0E, 0x0C, 0x0E, 0x08, 0x08,              //江陵，江夏，长沙，武陵，桂阳；
			0x08, 0x08, 0x08, 0x0E, 0x08,              //零陵，西城，永安，汉中，梓潼；
			0x12, 0x0C, 0x08, 0x08, 0x0E,              //成都，江州，建宁，云南，交趾；	
			0x0C, 0x08, 0x08, 0x08, 0x08               //倭，乌丸，羌，山越，南蛮。
			},
			{;thunk: Addr = 0x43B337,0x43B419,0x47FBDB,0x47FCFD
			}
			;兵役分割点代码会同时影响都市非兵役人口流动，所以将其调整为都市人口系数；通过加强中心削弱边角来尝试抑制“金角银边草肚皮”效应。
		}		
//show city draft
		__asm{;显示兵役
			;输入：[esp+0Ch]=总民心，[esp+8h]=都市民心，[esp+4h]=总增加兵役，[esp+28h]=都市指针
			;输出：eax=修正的显示增加兵役
			;空闲寄存器：eax,ecx,edx,edi,esi,ebp,ebx
			{;patch:
			pop         esi;保存返回地址到寄存器
			call        dword ptr [5FF32Ch];原函数，获得当前都市默认显示增加兵役
			push        esi;恢复返回地址
			mov         ecx, dword ptr [esp+28h];都市指针
			mov         edx, shared_draft
			call        edx 
			ret
		shared_draft:
			;输入：eax=增加兵役，ecx=都市指针
			;输出：eax=修正的增加兵役			
			push        edi
			mov         edi,eax;增加兵役
			mov         eax,[ecx];都市指针
			call        [eax+30h];获得都市所属势力
			test        eax,eax
			je          half;空城,增加兵役减半
			test        byte ptr [eax+34h],1;所属玩家势力?
			je          end
			mov         ecx,eax;玩家势力
			mov         eax,get_force_military_pop;获得势力总军事人口
			call        eax
			shr         eax,0Eh;兵力的基本单位=16384
			cmp         eax,7Fh;总军事人口超过字节大小
			jle         normal_draft
			mov         al, 7Fh
		normal_draft:
			mov         edx,edi;增加兵役
			shr         edx,2;增加兵役/4
			cmp         al,[cut_point+6];总军事人口<分隔点7
			jl          end
			sub         edi,edx增加兵役=>3/4
			cmp         al,[cut_point+7];总军事人口<分隔点8
			jl          end
			sub         edi,edx增加兵役=>1/2
			cmp         al,[cut_point+8];总军事人口<分隔点9
			jl          end
		half:
			shr         edi,1增加兵役=>1/2或1/4
		end:
			mov         eax,edi
			pop         edi
			ret
			},
			{;thunk: Addr = 0x43B426
			} 
			;ps:基本上是照搬老优化兵役代码，原代码兵役增量较大时，可能溢出而不显示，所以后移了thunk地址
			;另外，这里也可以像钱粮代码那样实现电脑兵役加倍功能，但优化界面暂时加不了选项了
		}
//add city draft
		__asm{;增加都市兵役人口时，处理“都市兵役不累加”和“电脑自动征兵”选项
			;输入：eax=[esp+4]=增加兵役人口，ecx=esi=都市
			;输出：
			;空闲寄存器：eax,ecx,edx
			{;patch:
			push	ecx 
			mov	edx, shared_draft
			call	edx 
			pop	ecx   
			mov	dword ptr [esp+4], eax 
			;以下是原代码
			push	edi
			lea 	edi, [esi+1C0h];&都市兵役人口
			cmp	byte ptr[not_add_draft], 0;“都市兵役不累加”flag!=0?
			jne 	update_city_draft
			add	eax, [edi];都市兵役人口+=增加兵役人口
			cmp	eax, 7A120h;<=50w?
			jle 	update_city_draft
			mov 	eax,7A120h;都市兵役人口=50w
		update_city_draft:
			mov	[edi], eax;保存都市兵役人口
			cmp	byte ptr[npc_auto_draft], 0;“电脑自动征兵”flag==0?
			je 	end
			mov 	ecx, [ecx+0CCh];都市所属军团
			test 	ecx, ecx;空城都市?
			jz 	end
			mov 	eax, [ecx+0B8h];所属势力
			test 	byte ptr[eax+34h], 1;所属玩家势力?
			jnz 	end
			mov 	eax, check_draft_food;检查军团的兵粮
			call 	eax
			test 	eax, eax
			jz 	end;军团兵粮不足，不征兵
			mov 	eax, [esi+88h];都市士兵数
			add 	eax, [edi];+=都市兵役人口
			push 	eax;保存征兵后士兵数
			xor 	eax, eax
			mov 	[edi], eax;都市兵役人口=0
			mov 	ecx, esi;都市
			mov 	eax, 4361C0h;获得都设兵力上限
			call 	eax
			pop 	edx;恢复征兵后士兵数
			sub 	eax, edx;兵力上限-征兵后士兵数
			test 	eax, eax;未超过兵力上限?
			jge 	update_city_soldier
			mov 	ecx, eax;临时变量
			neg 	eax;超出的兵力
			mov 	[edi], eax;都市兵役人口=超出的兵力
			add 	edx, ecx;征兵后士兵数 += 兵力上限-征兵后士兵数，即征兵后士兵数=兵力上限
		update_city_soldier:
			mov 	[esi+88h], edx;保存都市的士兵数
		end:
			pop 	edi
			ret 4
			},
			{;thunk: Addr = 0x47FD12
			}
		}
///////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////兵法伤害显示///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////
//heart attack damage 1
		__asm{;只显示当前势力攻心倒向士兵数
			;输入：esi=兵法任务指针，[esp+28h]=攻心兵法效果E，[esp+14h]=倒向部队大将
			;输出：
			;空闲寄存器：eax,ecx,edx
			{;patch:
			mov     eax, 00470E10h;原函数
			call    eax
			mov     eax, dword ptr [esp+28h];兵法效果E
			test    eax, eax;E=0，即兵法被识破？
			je      fail
			cmp     eax, 0Ah;E=10，即兵法成功？
			je      success
	    	contain:
		;兵法被减伤时，[esp+14h]被使用，这里需要再恢复
			mov     ecx, dword ptr [esi+3Ch];源部队
			mov     edx, dword ptr [ecx]
			call    dword ptr [edx+0BCh];获得部队大将
			mov     dword ptr [esp+14h], eax 
	    	success:
			add     dword ptr [esp], 7h;;修正返回地址，显示攻心伤害  
        		fail:	
			retn;默认地址返回，不显示攻心伤害
			},
			{;thunk: Addr = 0x505393
			call		patchAddr
			jmp		short 005053CDh
			jmp		long 005053CDh;把其他势力攻心成功时显示改为完全不显示
			}
		}
//heart attack damage 2
		__asm{;不需要特别设置也可以显示攻心伤害
			;输入：[esp+4]=&显示攻心伤害的文本，[esp+8]=2【进行记录】设为【详细】才显示，[esp+0Ch]=目标部队所在地图块，[esp+10h]=0目标部队势力颜色空
			;输出：[esp+8]=1，[esp+10h]=目标部队势力颜色
			;空闲寄存器：eax,ecx,edx
			{;patch:
			mov     byte ptr [esp+8], 1;1=不需要特别设置也可以显示攻心伤害
			mov     edx, dword ptr [esp+44h];目标部队势力颜色
			mov     dword ptr [esp+10h], edx;进行记录文本前的势力颜色方块
			push    47EEA0h;原函数
			retn
			},
			{;thunk: Addr = 0x5053C5
			}
		}
//damage record
		__asm{;进行记录兵法伤害：显示附加强度的伤害；兵法被抵挡或减伤时，也显示实际伤害
			;输入：ebx=目标部队势力，edi=源部队势力，[esp+1Ch]=兵法效果E，[esp+20h]=&兵法伤害
			;输出：修正的兵法伤害
			;空闲寄存器：eax,ecx,edx
			{;patch:
			;智力兵法起始地址，
			mov     eax, dword ptr [esp+1Ch];兵法效果E  
			test    eax, eax;E!=0?
			jnz     correct_damage_record
			push    004FE10Fh;兵法被识破,不用修正伤害,修改返回地址
			retn    4h 
			;武力兵法起始地址，武力兵法不用考虑E=0的情况
		correct_damage_record:
			mov     ecx, ebx;目标部队势力
			mov     eax, dword ptr [ecx]
			call    dword ptr [eax+3Ch];玩家势力
			test    eax, eax;目标势力不属于玩家? 
			je      normal
			mov     ecx, edi;源部队势力
			mov     eax, dword ptr [ecx]
			call    dword ptr [eax+3Ch]   
			test    eax, eax;目标势力属于玩家? 
			jnz     normal
			;一方属于玩家
			movzx   ecx, word ptr [12326FEh];强度 
			add     ecx, 64h;强度+100
			imul    ecx, dword ptr [esp+20h];(强度+100)*伤害
			mov     eax, 51EB851Fh
			imul    ecx
			sar     edx, 5h
			mov     eax, edx  
			shr     eax, 1F  
			add     edx, eax;(强度+100)*伤害/100   
			mov     dword ptr [esp+20h], edx;修正兵法伤害
        		normal:
			;双方都不属于玩家
			cmp     byte ptr [esp], 0D4h;返回地址=智力兵法?
			jnz     test_goal_soldier
			retn;智力兵法代码有下面功能代码,直接返回
	    	test_goal_soldier:
			mov     ecx, dword ptr [esi+40h];目标部队
		////////////////////////////////////////
		;代码是参考502930h()函数写的，这里被整迷糊了，似乎不要这段也可以，但原函数是这样
			;test    byte ptr [ecx+20h], 1
			;je      get_goal_soldier
			;mov     eax, <San9PK.462740H;部队所属都设指针>
			;call    eax
			;mov     ecx, eax 
		;get_goal_soldier:
		////////////////////////////////////////
			mov     	edx, dword ptr [ecx]
			call	dword ptr [edx+80h];目标部队士兵数
			cmp	eax, dword ptr [esp+20h];目标部队士兵数>=伤害?
			jge	end
			mov	dword ptr [esp+20h], eax;目标部队士兵数<伤害，伤害=目标部队士兵数	
        		end:	
			retn
			},
//intelligence damage record			
			{;thunk: Addr = 0x4FE0CD
			;智力兵法
			mov	eax，AddrDamageRecord
			call    	eax
			}
//strength damage record			
			{;thunk: Addr = 0x4FFD51
			;武力兵法
			push	esi;平衡堆栈地址
			call	AddrDamageRecord+10h	
			pop	esi;恢复堆栈地址			
			}
			;注意！两边兵法效果E和兵法伤害所在堆栈地址差4！调用函数起始地址也不一样！			
		}
//skip contained dialog
		__asm{;武力兵法未被抵挡时，不显示抵挡
			;输入：[esp+14h]=兵法效果E
			;输出：
			;空闲寄存器：eax,ecx,edx
			{;patch:
			},
			{;thunk: Addr = 0x4FFD7C
			cmp		dword ptr [esp+14h], 0Ah;E>=10?即兵法成功？
			jge		short 004FFDE1h;跳过抵挡代码
			}
			;武力兵法记录函数004FFD10()原来抵挡代码是在成功代码后面，两段代码分别有重复的结束代码，然后重复部分恰好够写入这个thunk
		}
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////组队功能////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
//set troop index
		__asm{;玩家从都设出征时【命令】为【攻击】，并且部队人数大于3时，根据大将ID和武将在部队中的统帅顺序生成【组队序列】。
			;输入：esi=部队大将，[esp+1Ch]=进军/攻击flag，[esp+40h]=&部队武将链表
			;输出：【组队序列】=>武将(0A2h)和(104h)
			;空闲寄存器：eax,ecx,edx
			{;patch:
			mov     eax, dword ptr [esp+1Ch];部队命令=攻击?
			test    eax, eax
			je      attack_troop
			mov     byte ptr [esp], 13h;调整返回地址 	
			retn
	    attack_troop:
			mov     byte ptr [esp], 27h;调整返回地址 
			push    edi
			push    ebx
			lea     ecx, dword ptr [esp+40h];部队武将链表
			mov     ebx, dword ptr [ecx+0Ch];部队武将链表项数，即部队武将数
			cmp     ebx, 3;部队武将数<=3?
			jle     end
			movzx   edx, word ptr [esi+4];部队大将ID 
			shl     edx, 4;部队大将ID<<4
			mov     edi, dword ptr [ecx+4];部队武将链表首项
	    loop:
			mov     ecx, dword ptr [edi+8];当前武将  
			mov     eax, ebx;当前武将序号
			or      eax, edx;当前武将序列=部队大将ID*16 + 当前武将序号
			mov     word ptr [ecx+0A2h], ax;【武将一览】点【武将】时的排序指标高16位 
			mov     word ptr [ecx+104h], ax;武将兵法标志bit32~47
			dec     ebx;武将序号--
			mov     edi, dword ptr [edi];部队武将链表下一项
			test    edi, edi;下一项为空?
			jnz     loop
		end: 
			pop     ebx
			pop     edi  
			retn
			},
			{;thunk: Addr = 0x48C00B
			}
			;ps:本游戏武将数不超过3FFh，所以【武将一览】点【武将】时的排序指标高16位本来是空余的；
			;兵法标志可保存，bit32~47对应兵法为水军/陷阱/射台/落石，武将不能直接有这些兵法，所以把【组队序列】写入到这里，已实现保存到存档的目的。
		}
//troop index
		__asm{;【出征】界面选择执行武将时按【组队序列】排列武将
			;输入：[esp+4]=&武将指针
			;输出：eax=武将排序指标
			;空闲寄存器：eax,ecx,edx
			{;patch:
			mov     eax, dword ptr [esp+4];&武将指针   
			mov     ecx, dword ptr [eax] 
			movzx   eax, word ptr [ecx+104h];武将【组队序列】
		/////////////////////////////////////////////////////	
			test    eax, eax;没有【组队序列】? 
			je      end
			mov     ecx, eax
			shr     eax, 4;【组队序列】>>4，即获得大将ID
			push    eax 
			mov     eax, 4531B0h;武将ID=>指针
			call    eax
			add     esp, 4 
			movzx   eax, byte ptr [eax+68h];大将统帅
			shl     eax, 10h;大将统帅<<16
			or      eax, ecx;排序指标 = 大将统帅<<16 + 【组队序列】
	    end: 
		/////////////////////////////////////////////////////
			retn
			},
			{;thunk: Addr = 0x4EA2E0
			}
			;出征时武将排序由按带兵能力排序改为按【组队序列】排序，后半部分代码实现不同【组队序列】之间再按大将统帅排列，暂时没更新到优化。		
		}
//troop advise
		__asm{;出征时按【组队序列】自动选中一组武将
			;输入：eax=[esp+4]=[esi+72Ch]=选中武将链表，edi=[esp+8]=可出征武将链表，ebx=[esp+0Ch]=最大可选项数=min(5,可出征武将数)，esi=任务指针
			;输出：自动选中武将=>选中武将链表
			;空闲寄存器：eax,ecx,edx,ebx,
			{;patch:
		///////////////////////////////cmp_troop_index////////////////////////////////////////////
			;武将筛选函数，检查【组队序列】中大将ID是否一致
			输入：[esp+4]=&武将，[esp+8]=设定对比值(大将ID)
			输出：eax=0不匹配，eax=1匹配
			push    edi
			mov     edi, dword ptr [esp+8];&武将
			mov     ecx, dword ptr [edi]
			mov     edx, dword ptr [ecx+0F4h];武将所属部队
			xor     eax, eax;默认不匹配
			test    byte ptr [edx+20h], 8;所属部队已出征?
			jnz     fail
			movzx   edx, word ptr [ecx+104h];武将【组队序列】
			test    edx, edx;【组队序列】=空?
			je      fail
			shr     edx, 4;【组队序列】>>4，即获得大将ID
			cmp     edx, dword ptr [edi+4];大将ID一致？
			sete    al;大将ID一致则eax置1，匹配
		fail:
			pop     edi											   
			retn
		//////////////////////////////TroopAdvise/////////////////////////////////////////////// 
			mov     edx, dword ptr [eax+0Ch];选中武将链表项数
			test    edx, edx;项数非零，即有已选中武将？	
			jnz     end
			mov     ebx, dword ptr [edi+4];可出征武将链表首项
		loop:
			mov     ecx, dword ptr [ebx+8];当前武将
			movzx   eax, word ptr [ecx+104h];当前武将【组队序列】
			test    eax, eax;【组队序列】=空?
			je      end
			shr     eax, 4;【组队序列】>>4，即获得大将ID
			push    0;不保留目标链表已有项
			push    eax;筛选函数对比值=大将ID 
			push    cmp_troop_index;筛选函数
			push    edi;源链表=可出征武将链表
			lea     ecx, dword ptr [esi+72Ch];目标链表=选中武将链表
			mov     eax, 46F3F0h;按筛选函数筛选源链表=>目标链表
			call    eax
			cmp     eax, 3;目标链表项数>=3
			jge     normal
			;这里利用0046F3F0h()函数的特性ecx保持不变
			mov     eax, 5180E0h;清空选中链表
			call    eax
			mov     ebx, dword ptr [ebx];可出征武将链表下一项
			test    ebx, ebx;下一项=空?
			jnz     loop
			jmp	 end;一开始少了这两个字节的命令，闹了个bug		
		normal:	
			push    dword ptr [esp+0Ch];n=最大可选项数=min(5,可出征武将数)
			mov     eax, 46EEB0h;保留选中链表前n项
			call    eax
		end:
			push    570500h;原函数
			retn
			},
			{;thunk: Addr = 0x4EA304
			}
			;ps:借鉴军师推荐代码而写；偷懒把子函数加在主函数前面了，注意thunk调用函数地址！
		}
//get troop index
		__asm{;读档循环生成【武将一览】点【武将】时的排序指标时，清除部分武将的【组队序列】，将未清除【组队序列】加入到排序指标
			;输入：ebp=[esp+4]=排序指标，ecx=esi=武将指针
			;输出：
			;空闲寄存器：eax,ecx,edx
			{;patch:
			movzx   eax, word ptr [ecx+104h];当前武将【组队序列】
			test    eax, eax;【组队序列】=空?  
			je      end
			mov     eax, dword ptr [ecx]
			call    dword ptr [eax+3Ch];武将属于玩家势力? 
			mov     ecx, esi;武将指针
			test    eax, eax
			je      clear_troop_index
			cmp     byte ptr [ecx+84h], 4;武将身份=俘虏?
			je      clear_troop_index
			mov     eax, dword ptr [ecx+0F4h];武将所属部队
			test    byte ptr [eax+20h], 8;所属部队已出征?
			jnz     add_troop_index
			push    edi  
			mov     edi, dword ptr [eax+64h];部队所属都设指针
			sub     esp, 40h;分配内存=2*武将链表(20h)
			mov     ecx, esp
			mov     eax, 470DF0h;初始化武将链表1 
			call    eax
			lea     ecx, dword ptr [esp+20h]
			mov     eax, 470DF0h;初始化武将链表2 
			call    eax
			mov     ecx, edi;武将所属都设
			push    esp;武将链表1
			mov     eax, 436C20h;ecx都设下属同势力武将链表=>push
			call    eax
			movzx   eax, word ptr [esi+104h];当前武将【组队序列】
			shr     eax, 4;【组队序列】>>4，即获得大将ID
			push    0;不保留目标链表已有项
			push    eax;筛选函数对比值=大将ID 
			push    cmp_troop_index;筛选函数 
			lea     edx, dword ptr [esp+0Ch]
			push    edx;源链表=武将链表1
			lea     ecx, dword ptr [esp+30h];目标链表=武将链表2
			mov     eax, 46F3F0h;按筛选函数筛选源链表=>目标链表
			call    eax  
			mov     edi, eax;武将链表2项数
			lea     ecx, dword ptr [esp+20h]
			mov     eax, 470E10h;释放武将链表2
			call    eax 
			mov     ecx, esp 
			mov     eax, 470E10h;释放武将链表1
			call    eax 
			add     esp, 40h;释放内存
			cmp     edi, 3;武将【组队序列】相同大将ID人数>=3
			pop     edi 
			mov     ecx, esi;武将 
			jge     add_troop_index
	    clear_troop_index:
			xor     eax, eax
			mov     word ptr [ecx+104h], ax;清除武将【组队序列】
			jmp     end
	    add_troop_index:
			mov     ax, word ptr [ecx+104h];读取武将【组队序列】
			add     word ptr [esp+6], ax;武将【组队序列】加入到排序指标 
	    end:
			push    44BFB0h;原函数：设置【武将一览】点【武将】时的排序指标
			retn
			},
			{;thunk: Addr = 0x4557F8
			}
			:循环里面插入代可以省不少事
		}
/////////////////////////////////////////////////////////////////////////////////////
//add npc ability
		__asm{;提高非玩家武将的能力
			;输入：ecx=武将指针，[esp+0Ch]=武将能力
			;输出：ecx=武将伤势，[esp+0Ch]=修正的武将能力
			;空闲寄存器：eax,edx
			{;patch:
			push	ecx;保存武将指针
			mov		eax,dword ptr [ecx]
			call	dword ptr [eax+3Ch];武将属于玩家势力?
			test	eax,eax
			jnz		end
			movzx	eax,byte ptr [anti_player_league_coef];写代码时借用了反玩家联盟系数	
			imul	eax,eax,0Ah;能力调整上限
			cmp		dword ptr [esp+0Ch],eax武将能力>=能力调整上限?
			jge		end
			add		eax,dword ptr [esp+0Ch]
			shr		eax,1
			mov		dword ptr [esp+0Ch],eax;调整后能力=(武将能力+能力调整上限)/2
		end:
			pop		ecx;恢复武将指针
			mov		ecx, dword ptr [ecx+80h];武将伤势
			retn
			},
			{;thunk: Addr = 0x44ED80
			}
			;代码尚未加入到优化，感觉加入的话提升难(quan)度(tui)效果满满
		}
////////////////////////////////////////////////////////////////////////////////////////		
		__asm{;发现一个可以节省代码的函数
			;输入：
			;输出：
			;空闲寄存器：eax,ecx,edx
			{;before:
			lea     ecx, dword ptr [esp+50]
			call    <4734B0h;初始化SquareList>
			lea     ecx, dword ptr [esp+10]
			call    <47A3C0h;建立路径信息对象>
			...
			push    地图块
			push    部队/设施
			lea     ecx, dword ptr [esp+18]
			call    <47A330h;p部队/设施到p1地图块的路径信息=>ecx>
			lea     ecx, dword ptr [esp+50]
			push	ecx
			lea     ecx, dword ptr [esp+14]
			call    <478290h;ecx路径信息=>push地图块链表>
			...
			lea     ecx, dword ptr [esp+14]
			call    <479F10h;释放路径信息对象>
			lea     ecx, dword ptr [esp+50]
			call    <4734D0h;释放SquareList>
			},
			{;after:
			lea     ecx, dword ptr [esp+50]
			call    <4734B0h;初始化SquareList>

			...
			push    地图块
			lea     ecx, dword ptr [esp+50]
			push	ecx
			mov     ecx, 部队/设施
			call    <45ED70h;ecx到push1的地图链表=>push>
			...

			lea     ecx, dword ptr [esp+50]
			call    <4734D0h;释放SquareList>			
			}
		}
		//
		__asm{;
			;输入：
			;输出：
			;空闲寄存器：eax,ecx,edx
			{;patch:
			},
			{;thunk: Addr = 
			}
		}
		
*/		